package cn.tedu.mall.seckill.service.Impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.pojo.seckill.dto.SeckillOrderItemAddDTO;
import cn.tedu.mall.pojo.seckill.model.SeckillStockLog;
import cn.tedu.mall.pojo.seckill.vo.SeckillSkuVO;
import cn.tedu.mall.seckill.mappers.SeckillSpuMapper;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;


/**
 * @author zhangyiping
 * @date 2024/1/19
 */
@Service
@DubboService
@Slf4j
public class SeckillSkuServiceImpl implements ISeckillSkuService {
    public static final String SECKILL_SKUS_PREFIX = "seckill:skus:";
    public static final String SECKILL_SKU_STOCK_PREFIX = "seckill:sku:stock:";

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillSpuMapper seckillSpuMapper;

    @Override
    public List<SeckillSkuVO> listSeckillSkus(Long spuId) {
        List<SeckillSkuVO> seckillSkuVOList = (List<SeckillSkuVO>) redisTemplate.opsForValue().get(SECKILL_SKUS_PREFIX + spuId);
        if (seckillSkuVOList == null || seckillSkuVOList.isEmpty()) {
            throw new CoolSharkServiceException(ResponseCode.NOT_FOUND, "秒杀sku列表查询为空，请检查预热逻辑");
        }
        return seckillSkuVOList;
    }

    @Override
    public void redusSeckillSkuCount(SeckillOrderItemAddDTO dto, String sn) {
        Long skuId = dto.getSkuId();
        Integer quantity = dto.getQuantity();
        int success = seckillSpuMapper.decrStock(skuId, quantity);
        if (success == 0) {
            throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST, "当前库存扣减失败，库存数量不足，skuId：" + skuId);
        }
        // 成功减一个库存，记录一条库存日志
        SeckillStockLog stockLog = new SeckillStockLog();
        stockLog.setSkuId(skuId);
        stockLog.setQuantity(quantity);
        stockLog.setOrderSn(sn);
        stockLog.setGmtCreate(LocalDateTime.now());
        stockLog.setGmtModified(stockLog.getGmtCreate());
        seckillSpuMapper.insertStockLog(stockLog);
    }

    @Override
    public void returnStock(String sn) {
        SeckillStockLog seckillStockLog = seckillSpuMapper.selectStockLogBySn(sn);
        if (seckillStockLog == null) {
            // 没有日志记录，说明库存没减
            log.info("sn:{}，没有对应的库存减少日志，不用进行任何操作", sn);
        } else {
            // 还库存
            seckillSpuMapper.incrStock(seckillStockLog.getSkuId(), seckillStockLog.getQuantity());
        }
    }
}
